# -*- coding: utf-8 -*-
# created on 2017/03/29

from sympy import sympify
from mathsolver.functions.base import BaseFunction, BaseIneq, BaseEq, BaseIneqs, BaseBelong, BaseFunc, new_latex
from mathsolver.functions.budengshi.common_opers import ineqs_symbs
from mathsolver.functions.hanshu.helper import reverse_op, ineq_expr_list_2_interval2
from mathsolver.functions.hanshu.zuizhi_new import MinValue
from mathsolver.functions.sympy_utils import default_symbol

op_group1 = {'>', '>='}
op_group2 = {'<', '<='}


class ProofHanShuBuDengShi(BaseFunction):
    """ 证明函数不等式（含参数、不含参数）
    输入：最后一项是 不等式；前面的输入可以有参数范围，变量范围，都是 optional 的"""

    def solver(self, *args):

        # 输入的最后一项是 BaseIneq, 或者 BaseIneqs
        pf_ineq = args[-1]

        if isinstance(pf_ineq, BaseIneqs):
            for BaseIneq_arg in pf_ineq.value:
                pf_ineq_piece = BaseIneq(BaseIneq_arg)
                self.steps.append(["", "- 证明 %s" % pf_ineq_piece.printing()])
                new_args = args[:-1] + (pf_ineq_piece,)
                solver = ProofHanShuBuDengShi().solver(*new_args)
                self.steps.extend(solver.steps)
            self.steps.append(["", "综上所述，有 %s" % pf_ineq.printing()])
            self.label.add("证明函数不等式")
            return self

        pf_left, pf_op, pf_right = pf_ineq.value

        # 将不等式统一转化成 f(x) >/>= 0 格式
        if pf_op in op_group2:
            pf_op = reverse_op(pf_op)
            pf_expr = sympify(pf_right) - sympify(pf_left)
        else:
            pf_expr = sympify(pf_left) - sympify(pf_right)

        self.steps.append(["", "问题等价于证明 %s %s 0" % (new_latex(pf_expr), pf_op)])

        # 从表达式里面计算 变量/参数 符号
        var_symbol = default_symbol(pf_expr)

        # 分析输入，是否给定变量范围/参数范围
        var_qujian = None
        canshu_qujian = {}
        if len(args) > 1:
            for arg in args[:-1]:

                if isinstance(arg, (BaseIneq, BaseIneqs)):
                    arg_value = arg.value
                    symb = sympify(ineqs_symbs(arg_value)[0])
                    qujian = ineq_expr_list_2_interval2(arg_value)
                elif isinstance(arg, BaseBelong):
                    symb = arg.var
                    qujian = arg.interval
                if symb == var_symbol:
                    var_qujian = qujian
                else:
                    canshu_qujian = {symb: qujian}

        # 证明左边函数最小值 >/>= 0
        if var_qujian:
            min_solver = MinValue(known=canshu_qujian).solver(BaseEq(['y', pf_expr]), var_qujian)
        else:
            min_solver = MinValue(known=canshu_qujian).solver(BaseEq(['y', pf_expr]))

        self.steps.extend(min_solver.steps)
        min_solver_result = min_solver.output[0].value

        # 不含参数
        if isinstance(min_solver_result, list):
            min_val, (_, _) = min_solver_result
            # 补充：如果最值算出来含有参数，计算最值的最值
            if min_val.has(min_solver.canshu):
                min_solver2 = MinValue(known=canshu_qujian).solver(
                    BaseFunc({'var': min_solver.canshu, 'expression': min_val, 'type': '', 'name': 'f'})).output[0].value
                self.steps.append(["", "又 %s 的最小值为 %s" % (new_latex(min_val), new_latex(min_solver2[0]))])

            self.steps.append(["", "所以 %s %s 0 恒成立，得证" % (new_latex(pf_expr), pf_op)])
        else:
            for canshu_range, zuizhi in min_solver_result.items():
                min_val, (_, _) = zuizhi
                # 补充：如果最值算出来含有参数，计算最值的最值（现在只考虑一个分段的情况）
                if min_val.has(min_solver.canshu):
                    min_solver2 = MinValue(known=canshu_qujian).solver(
                        BaseFunc({'var': min_solver.canshu, 'expression': min_val, 'type': '', 'name': 'f'})).output[0].value
                    self.steps.append(["", "又当 %s 属于 %s 时 %s 的最小值为 %s"
                                       % (new_latex(min_solver.canshu), new_latex(canshu_range), new_latex(min_val), new_latex(min_solver2[0]))])
                self.steps.append(["", "所以当 %s 属于 %s 时，所以 %s %s 0 恒成立" %
                                   (new_latex(min_solver.canshu), new_latex(canshu_range), new_latex(pf_expr), pf_op)])

            self.steps.append(["", "比较各个参数范围与各个分段上的最值可知 %s %s 0 恒成立，得证" % (new_latex(pf_expr), pf_op)])

        self.label.add("证明函数不等式")
        return self


if __name__ == '__main__':
    pass
